import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.Types;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Properties;
import java.util.Date;

/**
 * @owner: bwx1115623
 * @time:  2023/1/29
 **/

public class Opengauss_Function_MultiNodeWrite_Case0039 {
	static public String driver = "org.postgresql.Driver";
	static public String tb_name;
	static public String func_name;
	static public String proc_name;
    public static Properties getConfigFromFile(String filePath) {
        Properties props = new Properties();
        try {
            BufferedInputStream config = new BufferedInputStream(new FileInputStream(filePath));
            props.load(config);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return props;
    }

    public static String genURLFromPro(Properties props) {
        String hostname = props.getProperty("hostname");
        String[] hostnames = hostname.split(",");
        String port = props.getProperty("port");
        String[] ports = port.split(",");
        String dbname = props.getProperty("dbname");
		tb_name = props.getProperty("tbname");
		func_name = props.getProperty("funcname");
		proc_name = props.getProperty("procname");
        return genURLFromHostsPortsDBname(hostnames, ports, dbname);
    }

    public static String genURLFromHostsPortsDBname(String[] hostnames, String[] ports, String dbname) {
        String sourceURL;
        if (hostnames.length == 1) {
            sourceURL = "jdbc:postgresql://" + hostnames[0] + ":" + ports[0] + "/" + dbname;
        } else {
            ArrayList<String> ip_port_pare = new ArrayList<>();
            if (ports.length == 1) {
                for (String ip : hostnames) {
                    ip_port_pare.add(ip + ":" + ports[0]);
                }
            } else {
                for (int i = 0; i < hostnames.length; i++) {
                    ip_port_pare.add(hostnames[i] + ":" + ports[i]);
                }
            }
            sourceURL = "jdbc:postgresql://" + String.join(",", ip_port_pare) + "/" + dbname;
        }
        return sourceURL;
    }

    public static Connection GetConnection(Properties props) {
        Connection connR;
        String sourceURL = genURLFromPro(props);
        System.out.println(sourceURL);
        try {
            Class.forName(driver).newInstance();
            connR = DriverManager.getConnection(sourceURL, props);
        } catch (Exception var10) {
            var10.printStackTrace();
            return null;
        }
        return connR;
    }
	  
	public static void ExecCallableFunction(Connection conn) {
	    CallableStatement cstmt = null;
	    try {
	        cstmt=conn.prepareCall("{? = call " + func_name + "()}");
	        cstmt.registerOutParameter(1, Types.INTEGER);
	        cstmt.execute();
	        Integer res = cstmt.getInt(1);
	        System.out.println("The CallableStatment " + func_name + " returns:" + res);
	        cstmt.close();
	    } catch (SQLException e) {
	        if (cstmt != null) {
	        try {
	            cstmt.close();
	        } catch (SQLException e1) {
	            e1.printStackTrace();
	        }
	        }
	        e.printStackTrace();
	    }
	}
	  
	public static void ExecCallableProcedure(Connection conn) {
		CallableStatement cstmt = null;
		try {
		    cstmt=conn.prepareCall("{? = call " + proc_name + "()}");
		    cstmt.registerOutParameter(1, Types.OTHER);
		    cstmt.execute();
		    ResultSet res = cstmt.getResultSet();
		    System.out.println("The CallableStatment " + proc_name + " returns:" + res);
		    cstmt.close();
		} catch (SQLException e) {
		    if (cstmt != null) {
		        try {
		          cstmt.close();
		        } catch (SQLException e1) {
		          e1.printStackTrace();
		        }
		    }
		    e.printStackTrace();
		}
	}
	  
	public static void QueryInAnonymousBlock(Connection conn) {
		PreparedStatement pstmt = null;
		try {
		    pstmt = conn.prepareStatement("declare "
		      		+ "begin "
		      		+ "execute immediate 'select * from " + tb_name + ";';"
		      		+ "end;");
		    int rowcount = pstmt.executeUpdate();
		    pstmt.close();
		} catch (SQLException e) {
		    if (pstmt != null) {
		        try {
		          pstmt.close();
		        } catch (SQLException e1) {
		          e1.printStackTrace();
		        }
		    }
		    e.printStackTrace();
		}
	}

    public static void main(String[] args) {
        Properties pros = new Properties();
        Properties pros_conf=null;
        String jdbc_config_file = null;
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "--config-file":
                    jdbc_config_file = args[i + 1];
                    pros_conf=getConfigFromFile(jdbc_config_file);
                    break;
                case "-F":
                    jdbc_config_file = args[i + 1];
                    pros_conf=getConfigFromFile(jdbc_config_file);
                    break;
                default:
                    break;
            }
        }
        //建立连接
        if (pros_conf!=null){
            //以参数为准，覆盖配置文件中的
            pros_conf.putAll(pros);
        }
        Connection conn = GetConnection(pros_conf);
	    Statement stmt = null;
	    ExecCallableFunction(conn);
	    ExecCallableProcedure(conn);
	    QueryInAnonymousBlock(conn);

	    try {
	      conn.close();
	    } catch (SQLException e) {
	      e.printStackTrace();
	    }
	}
}
